package com.efounder.message.manager;

import android.util.Log;

import com.efounder.constant.EnvironmentVariable;
import com.efounder.integral.JFChatIntegralManager;
import com.efounder.message.db.MessageDBHelper;
import com.efounder.message.db.MessageDBManager;
import com.efounder.message.db.MessageModelDBManager;
import com.efounder.message.model.MessageModel;
import com.efounder.message.socket.JFSocketManager;
import com.efounder.message.struct.IMStruct;
import com.efounder.message.struct.IMStruct002;
import com.efounder.message.struct.IMStruct003;
import com.efounder.message.struct.IMStructUtil;
import com.efounder.util.AppContext;
import com.efounder.util.DateUtil;
import com.efounder.util.JFThreadPoolUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class JFMessageManager {
    private static final String TAG = "JFMessageManager";
    public static long sessionTime;
//	public static boolean isChannelActive = false;

    private static JFMessageManager manager;
    public static MessageDBManager dbManager;
    public static MessageModelDBManager messageModelDBManager;

    private static long TIMEOUT = 60;
    public boolean isSendMessageThreadRunning = true;

    // 监听列表
    private List<JFMessageListener> listenerList = new ArrayList<JFMessageListener>();

    private static BlockingQueue<IMStruct> messageQueue = new LinkedBlockingQueue<IMStruct>();
    private static BlockingQueue<IMStruct> readMessageQueue = new LinkedBlockingQueue<IMStruct>();


    private Map<String, MessageModel> messageMap = new HashMap<String, MessageModel>();
    private Map<String, IMStruct002> messageKeyMap = new HashMap<String, IMStruct002>();

    private SendMessageThread sendMessageThread;
    private Object waitObj = new Object();

    private static MessageDBHelper sqlHelper;

    //当前正在发送的消息
    private IMStruct002 currentMessage;
    //当前正在发送的消息的第一次发送时间
    private Date currentDate;

    public JFMessageManager() {
        //启动发送消息队列
        sendMessageThread = new SendMessageThread();
        sendMessageThread.start();
    }

    /**
     * 单例
     *
     * @return
     */
    public static JFMessageManager getInstance() {
        if (manager == null) {
            manager = new JFMessageManager();
            // 初始化数据库
            sqlHelper = new MessageDBHelper(
                    AppContext.getInstance());
            dbManager = MessageDBManager.getInstance();
            messageModelDBManager = new MessageModelDBManager(sqlHelper);
        }
        return manager;
    }

    private class SendMessageThread extends Thread {
        @Override
        public void run() {
            super.run();
            while (isSendMessageThreadRunning) {
                try {
                    sendMessageQueue();
                    sendReadMessageQueue();
//					Thread.sleep(1000);
                    synchronized (waitObj) {
                        waitObj.wait(1000);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 发送队列消息
     */
    private void sendMessageQueue() {
        //todo yqs 屏蔽下一行，因为下一行不屏蔽断网后发送消息一直不会失败
//        if (!isChannelActived()) return;
        //取出最后一个消息发送
        IMStruct002 queueLastMessage = (IMStruct002) messageQueue.peek();
        if (queueLastMessage == null) {
            return;
        }

        //如果当前正在发送的消息为空或者和队列头部的消息不是一个消息
        // 队列头部的消息是第一次发送 记录当前时间 用于超时判断
        if (currentMessage == null || currentMessage != queueLastMessage) {
            currentDate = new Date();
            currentMessage = queueLastMessage;
            this.changeMessageState(IMStruct002.MESSAGE_STATE_SENDING, queueLastMessage);
        }
        //判断超时 把消息设置为发送失败 移除队列
        long second = DateUtil.diffSecond(System.currentTimeMillis(), currentDate.getTime());
        if (second > TIMEOUT) {
            this.changeMessageState(IMStruct002.MESSAGE_STATE_FAILURE, queueLastMessage);
            messageQueue.poll();
            currentMessage = null;
        } else if (queueLastMessage.getState() == IMStruct002.MESSAGE_STATE_DELETE) {
            messageQueue.poll();
            currentMessage = null;
        } else {
            //发送消息
            this.sendStruct(queueLastMessage, queueLastMessage.getMessageID());
        }
    }

    /**
     * 发送队列已读消息
     */
    private void
    sendReadMessageQueue() {
        if (isChannelActived()) {//取出最后一个消息发送
            IMStruct002 queueLastMessage = (IMStruct002) readMessageQueue.peek();
            if (queueLastMessage == null) {
                return;
            }

            this.sendStruct(queueLastMessage, queueLastMessage.getMessageID());
        } else {
            return;
        }
    }

    /**
     * 增加消息监听 (使用完毕要调用移除监听方法)
     *
     * @param listener
     */
    public void addMessageListener(String userID, JFMessageListener listener) {
//		不包含对象
        if (!listenerList.contains(listener)) {
            listenerList.add(listener);
        }
    }

    /**
     * 移除监听
     *
     * @param listener
     */
    public void removeMessageListener(String userID, JFMessageListener listener) {
        listenerList.remove(listener);
    }

    /**
     * 获取消息列表
     *
     * @param userID
     * @param toUserType
     * @return
     */
    public List<IMStruct002> getMessageList(int userID, byte toUserType) {
        String uID = IMStructUtil.getUserID(toUserType, userID);
        MessageModel messageModel = this.getMessageModel(uID, toUserType);
        return messageModel.getList();
    }

    /**
     * 获取个人历史消息
     *
     * @param fromUserId
     * @param toUserId
     * @param msgID
     * @param msgNum
     * @param handler
     * @return
     */
    public List<IMStruct002> getPersonalHistoryMessage(int fromUserId,
                                                       int toUserId, String msgID, int msgNum, JFMessageHandler handler) {
        List<IMStruct002> historyMessageList = null;
        // 从数据库取消息
        historyMessageList = dbManager.queryPersonalLessThan(fromUserId,
                toUserId, msgID, msgNum);

        if (historyMessageList == null) {
            // 从服务器取

            // 存到本地

        }

        IMStruct002 message = new IMStruct002();
        message.setToUserId(toUserId);
        message.setFromUserId(fromUserId);
        message.setToUserType((byte) 0);
        MessageModel messageModel = this.getMessageModel(message);

        IMStruct002 messageTemp = null;
        for (int i = 0; i < historyMessageList.size(); i++) {
            messageTemp = historyMessageList.get(i);
            messageModel.getList().add(i, messageTemp);
            messageModel.getMap().put(messageTemp.getMessageID(), messageTemp);
            messageKeyMap.put(messageTemp.getMessageID(), messageTemp);
            if ((messageTemp.getState() != IMStruct002.MESSAGE_STATE_SENDING && messageTemp.getState() != IMStruct002.MESSAGE_STATE_WAITSEND) || messageTemp.getFromUserId() != Integer.parseInt(EnvironmentVariable.getUserID())) {
                continue;
            }
            messageQueue.offer(messageTemp);
        }
        return historyMessageList;
    }

    /**
     * 获取群组历史消息
     *
     * @param groupToUserId
     * @param msgID
     * @param msgNum
     * @param handler
     * @return
     */
    public List<IMStruct002> getGroupHistoryMessage(int groupToUserId,
                                                    String msgID, int msgNum, JFMessageHandler handler) {
        List<IMStruct002> historyMessageList = null;
        // 从数据库取消息
        historyMessageList = dbManager.queryGroupLessThan(groupToUserId, msgID,
                msgNum);

        if (historyMessageList == null) {
            // 从服务器取

            // 存到本地

        }

        String uID = IMStructUtil.getUserID((byte) 1, groupToUserId);
        MessageModel messageModel = this.getMessageModel(uID, (byte) 1);

        IMStruct002 messageTemp = null;
        for (int i = 0; i < historyMessageList.size(); i++) {
            messageTemp = historyMessageList.get(i);
            messageModel.getList().add(i, messageTemp);
            messageModel.getMap().put(messageTemp.getMessageID(), messageTemp);

            messageKeyMap.put(messageTemp.getMessageID(), messageTemp);
            if ((messageTemp.getState() == IMStruct002.MESSAGE_STATE_SENDING || messageTemp.getState() == IMStruct002.MESSAGE_STATE_WAITSEND) && messageTemp.getFromUserId() == Integer.parseInt(EnvironmentVariable.getUserID())) {
                messageQueue.offer(messageTemp);
            }
        }
        return historyMessageList;
    }

    /**
     * 预发送消息
     *
     * @param message
     * @return
     */
    public boolean preSendMessage(IMStruct002 message) {
        message.setMsgId((int) (1 + Math.random() * (10000 - 1 + 1)));
        message.setLocalTime(System.currentTimeMillis());
        // 存到消息Map中
        MessageModel messageModel = this.getMessageModel(message);
        messageModel.add(message);
        messageKeyMap.put(message.getMessageID(), message);
        //消息默认发送中状态
        this.changeMessageState(IMStruct002.MESSAGE_STATE_PRESEND, message, false);
        // 存到SQLite中
        dbManager.insert(message);
        return true;
    }

    /**
     * 发送预消息
     *
     * @param message
     * @return
     */
    public boolean sendPreMessage(IMStruct002 message) {
        //添加到消息队列
        messageQueue.offer(message);
        return true;
    }

    /**
     * 发送消息
     *
     * @param message
     * @return
     */
    public boolean sendMessage(IMStruct002 message) {
        message.setMsgId((int) (1 + Math.random() * (10000 - 1 + 1)));
        message.setServerTime(0);
        message.setLocalTime(System.currentTimeMillis());
        //执行此方法，给message设置一个id
        message.getMessageID();
        //todo 系统消息不放入队列发送
        //撤回消息时发送的系统消息类型（还可以用来发送系统消息，比如正在输入中,cmd消息） 103
        if (message.getMessageChildType() == 103) {
            sendNoQueueMessage(message);
            return true;
        }

        //系统消息只发送 不存入messageModel
        if (message.getMessageChildType() < (short) 100) {
            // 存到消息Map中
            MessageModel messageModel = this.getMessageModel(message);
            messageModel.add(message);
        }

        messageKeyMap.put(message.getMessageID(), message);
        //添加到消息队列
        messageQueue.offer(message);
        //消息默认发送中状态
        this.changeMessageState(IMStruct002.MESSAGE_STATE_WAITSEND, message);
        // 存到SQLite中
        dbManager.insert(message);
        return true;
    }

    /**
     * 发送不加入队列的消息（比如一些正在输入的系统消息）
     *
     * @param message
     * @return
     */
    public boolean sendNoQueueMessage(final IMStruct002 message) {
        message.getMessageID();
        message.setMsgId((int) (1 + Math.random() * (10000 - 1 + 1)));
        message.setServerTime(0);
        message.setLocalTime(System.currentTimeMillis());
        //使用线程池在线程中发送消息
        JFThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                sendStruct(message, message.getMessageID());
            }
        });
        return true;
    }

    public boolean sendFormMessage(int userID, String messageString) {
        this.sendFormMessage(userID, -1, messageString);
        return true;
    }

    public boolean sendFormMessage(int userID, int pUserID, String messageString) {
        IMStruct002 message = new IMStruct002();
        message.setFromUserId(Integer.parseInt(EnvironmentVariable.getUserID()));
        message.setToUserId(userID);
        message.setTime(new Date().getTime());
        message.setServerTime(0);
        message.setBody(messageString.getBytes());
        message.setToUserType((byte) 0);
        message.setMessageChildType((byte) 31);
        if (pUserID >= 0) {
            message.setpUserId(pUserID);
        }
        this.sendMessage(message);
        return true;
    }

    /**
     * 消息重发
     *
     * @param message
     * @return
     */
    public boolean reSendMessage(IMStruct002 message) {
        //拿到之前的消息  删除
//        messageKeyMap.put(message.getMessageID(), null);
        messageKeyMap.remove(message.getMessageID());

        MessageModel messageModel = this.getMessageModel(message);
        messageModel.getList().remove(message);
        messageModel.getMap().remove(message.getMessageID());
        dbManager.delete(message);

        // todo yqs消息id重新生成(设置为null 在get的时候就会重新生成)
        message.setMessageID(null);
        // 生成新的时间  发送
        message.setTime(new Date().getTime());
        messageModel.add(message);
        messageKeyMap.put(message.getMessageID(), message);
        //添加到消息队列
        messageQueue.offer(message);
        //消息默认发送中状态
        this.changeMessageState(IMStruct002.MESSAGE_STATE_SENDING, message);
//		message.setState(IMStruct002.MESSAGE_STATE_SENDING);
        // 存到SQLite中
        dbManager.insert(message);
        return true;
    }

    /**
     * 发送已读消息
     *
     * @param message
     * @return
     */
    public boolean sendReadMessage(IMStruct002 message) {
        if (message.getFromUserId() == Integer.parseInt(EnvironmentVariable.getUserID()) || message.getToUserType() != (byte) 0) {
            return false;
        }

        message.setReadState(IMStruct002.MESSAGE_STATE_READ);
        MessageModel messageModel = this.getMessageModel(message);
        messageModel.messageRead(message);

        IMStruct002 messageTemp = new IMStruct002();
        messageTemp.setBody(message.getMessageID().getBytes());
        messageTemp.setMsgLength(42);
        messageTemp.setMessageChildType((short) 102);        // 102  已读
//		messageTemp.setMessageID(message.getMessageID());
        messageTemp.setFromUserId(message.getToUserId());
        messageTemp.setToUserId(message.getFromUserId());
        messageTemp.setToUserType((byte) 0);
        messageTemp.setMsgId(message.getMsgId());
        messageTemp.setServerTime(message.getServerTime());
        messageTemp.setTime(new Date().getTime());
        //添加到消息队列
        readMessageQueue.offer(messageTemp);
        dbManager.update(message);
        return true;
    }

    public boolean removeMessage(IMStruct002 message) {
        MessageModel messageModel = this.getMessageModel(message);
        if (messageModel != null) {
            messageModel.remove(message);
        }
        IMStruct002 messageTemp = messageKeyMap.get(message.getMessageID());
        //如果在内存中找不到直接更新到数据库中
        if (messageTemp == null) {
            message.setEnable(false);
            dbManager.updateMessageState(message.getMessageID(), IMStruct002.MESSAGE_STATE_DELETE);
            return true;
        }
        messageTemp.setEnable(false);
        this.changeMessageState(IMStruct002.MESSAGE_STATE_DELETE, messageTemp);
        return true;
    }

    public boolean updateMessage(IMStruct002 message) {
        dbManager.update(message);
        //更新最后一条消息中的消息
        MessageModel messageModel = this.getMessageModel(message);
        if (messageModel != null) {
            messageModel.setLastMessage(message);
        }
        return true;
    }

    /**
     * 根据消息id查询消息
     *
     * @param msgID
     * @return
     */
    public IMStruct002 queryMessage(String msgID) {
        IMStruct002 message = null;
        //查询数据库取出消息
        IMStruct002 struct002 = dbManager.queryForID(msgID);
        if (struct002 == null) {
            return null;
        }
        //根据查出的消息判断内存中是否存在
        MessageModel messageModel = this.getMessageModel(struct002);
        if (messageModel != null) {
            message = messageModel.get(struct002.getMessageID());
            if (message == null) {
                message = struct002;
            }
        }
        return message;
    }

    /**
     * 发送struct
     *
     * @param struct
     * @return
     */
    public boolean sendStruct(IMStruct struct) {
        JFSocketManager.sendMessage(struct.toByteArray());
        return true;
    }

    public boolean sendStruct(IMStruct struct, String messageID) {
        JFSocketManager.sendMessage(struct.toByteArray(), messageID);
        return true;
    }

    /**
     * 发送回执
     *
     * @param message
     */
    public void sendReceipt(IMStruct002 message) {
        IMStruct003 struct = new IMStruct003();
        struct.setAckType((byte) 0);
        struct.setTime(System.currentTimeMillis());
        struct.setMsgId((IMStructUtil.getMsgId(message)));
        Log.d("messagemanager:", "收到消息给服务器发回执：" + message.getMessageID() + " " + message.getMessageChildType());
        this.sendStruct(struct);
    }

    private MessageModel getMessageModel(IMStruct002 message) {
        return getMessageModel(message.getUserID(), message.getToUserType());
    }

    private MessageModel getMessageModel(String UserID, byte toUserType) {
        MessageModel messageModel = messageMap.get(UserID);
        //map没有去数据库查
        if (messageModel == null) {
            messageModel = messageModelDBManager.query(UserID);
            messageMap.put(UserID, messageModel);
        }
        //数据库没有 new
        if (messageModel == null) {
            messageModel = new MessageModel();
            messageModel.setUserID(UserID);
            messageModel.setUserType(toUserType);
            messageMap.put(messageModel.getUserID(), messageModel);
        }
        return messageModel;
    }

    /**
     * 获取最后一条消息
     *
     * @param userID
     * @param toUserType
     * @return
     */
    public IMStruct002 getLastMessage(int userID, byte toUserType) {
        String uID = IMStructUtil.getUserID(toUserType, userID);

        MessageModel model = this.getMessageModel(uID, toUserType);
        if (model == null) {
            return null;
        }

        return model.getLastMessage();
    }

    /**
     * 收到消息 派发onReceive
     *
     * @param message
     */
    public void messageReceive(IMStruct002 message) {
        //给服务器发送回执
        this.sendReceipt(message);
        //已送达
        if (message.getMessageChildType() == (short) 101) {
            IMStruct002 messageTemp = messageKeyMap.get(message.getMessage());
            //如果在内存中找不到直接更新到数据库中
            if (messageTemp == null) {
                messageTemp = dbManager.queryForID(message.getMessage());
//				dbManager.updateMessageState(message.getMessage(), IMStruct002.MESSAGE_STATE_RECEIVE);
//				return;
                if (messageTemp == null) {
                    return;
                }
            }
            JFChatIntegralManager.handleIntegralMessage(messageTemp, message);
            this.changeMessageState(IMStruct002.MESSAGE_STATE_RECEIVE, messageTemp);
        }
        //已读
        else if (message.getMessageChildType() == (short) 102) {
            IMStruct002 messageTemp = messageKeyMap.get(message.getMessage());
            //如果在内存中找不到直接更新到数据库中
            if (messageTemp == null) {
                messageTemp = dbManager.queryForID(message.getMessage());
//				dbManager.updateMessageState(message.getMessage(), IMStruct002.MESSAGE_STATE_READ);
//				return;
                if (messageTemp == null) {
                    return;
                }
            }
            JFChatIntegralManager.handleIntegralMessage(messageTemp, message);
            this.changeMessageState(IMStruct002.MESSAGE_STATE_READ, messageTemp);
        }
        //系统消息 只派发事件 不做处理
        else if (message.getMessageChildType() >= (short) 100) {
            IMStruct002 messageTemp = messageKeyMap.get(message.getMessageID());
            if (messageTemp != null) {
                Log.d(TAG, "系统消息去重：" + message.getMessageID());
                return;
            }
            messageKeyMap.put(message.getMessageID(), message);

            for (int i = 0; i < listenerList.size(); i++) {
                JFMessageListener listener = listenerList.get(i);
                listener.onReceive(message);
            }
        }
        //消息
        else {
            //消息去重
            IMStruct002 messageTemp = messageKeyMap.get(message.getMessageID());
            if (messageTemp != null) {
                Log.d(TAG, "非系统消息去重" + message.getMessageID());
                return;
            }
            message.setLocalTime(System.currentTimeMillis());
            JFChatIntegralManager.handleIntegralMessage(message, message);
            // 存到消息Map中
            MessageModel messageModel = this.getMessageModel(message);
            messageModel.add(message);
            messageKeyMap.put(message.getMessageID(), message);

            for (int i = 0; i < listenerList.size(); i++) {
                JFMessageListener listener = listenerList.get(i);
                listener.onReceive(message);
            }
        }
        // 收到的消息插入SQLite
        dbManager.insert(message);
    }

    public void messageDeliver(String messageID) {
        if (messageID == null || messageID.equals("")) {
            return;
        }
        IMStruct002 message = null;
        IMStruct002 queueLastMessage = (IMStruct002) messageQueue.peek();
        IMStruct002 queueLastReadMessage = (IMStruct002) readMessageQueue.peek();
        //如果消息在队列最后 移除
        if (queueLastMessage != null && queueLastMessage.getMessageID().equals(messageID)) {
            message = messageKeyMap.get(messageID);
            messageQueue.poll();
            synchronized (waitObj) {
                waitObj.notifyAll();
            }
            if (message != null) {
                this.markedAsDliver(message);
            }
        } else if (queueLastReadMessage != null && queueLastReadMessage.getMessageID().equals(messageID)) {
            readMessageQueue.poll();
            synchronized (waitObj) {
                waitObj.notifyAll();
            }
        }
    }

    public void messageDeliverFailure(String messageID) {
        if (messageID == null || messageID.equals("")) {
            return;
        }
        IMStruct002 message = null;
        IMStruct002 queueLastMessage = (IMStruct002) messageQueue.peek();
        //如果消息在队列最后 移除
        if (queueLastMessage != null && queueLastMessage.getMessageID().equals(messageID)) {
            message = messageKeyMap.get(messageID);
            messageQueue.poll();
            synchronized (waitObj) {
                waitObj.notifyAll();
            }
            if (message != null) {
                this.changeMessageState(IMStruct002.MESSAGE_STATE_FAILURE, message);
            }
        }
    }

    /**
     * 收到回执消息
     *
     * @param struct
     */
    public void receiptReceive(IMStruct003 struct) {
        String messageID = struct.getMsgId();
        if (messageID == null || messageID.equals("")) {
            return;
        }
        IMStruct002 queueLastReadMessage = (IMStruct002) readMessageQueue.peek();
        //如果是已查看的回执 直接移除队列
        if (queueLastReadMessage != null && queueLastReadMessage.getMessageID().equals(messageID)) {
            readMessageQueue.poll();
            synchronized (waitObj) {
                waitObj.notifyAll();
            }
        }
        //如果是消息的回执 单独处理
        IMStruct002 queueLastMessage = (IMStruct002) messageQueue.peek();
        //如果消息在队列最后 移除
        if (queueLastMessage != null) {
            if (queueLastMessage.getMessageID().equals(messageID)) {
                messageQueue.poll();
                synchronized (waitObj) {
                    waitObj.notifyAll();
                }
            }
            if (queueLastMessage.getMessageChildType() == (short) 102) {
                this.markedAsRead(queueLastMessage);
            } else {
                this.markedAsSend(queueLastMessage);
            }
        }
    }

    /**
     * 获取当前聊天 @我的消息的index
     *
     * @param userID
     * @param toUserType
     * @return
     */
    public int getAtMessageIndex(int userID, byte toUserType) {
        IMStruct002 message = new IMStruct002();
        message.setToUserId(userID);
        message.setFromUserId(userID);
        message.setToUserType(toUserType);

        MessageModel model = this.getMessageModel(message);
        if (model == null) {
            return -1;
        } else {
            int index = model.getAtMessageIndex();
            return index;
        }
    }

    /**
     * 获取是否含有@我的消息
     *
     * @param userID
     * @param toUserType
     * @return
     */
    public boolean getHasAtMeMessage(int userID, byte toUserType) {
        IMStruct002 message = new IMStruct002();
        message.setToUserId(userID);
        message.setFromUserId(userID);
        message.setToUserType(toUserType);

        MessageModel model = this.getMessageModel(message);
        if (model == null) {
            return false;
        } else {
            String atMessageID = model.getAtMessageID();
            if (!"".equals(atMessageID)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 清除当前的@
     *
     * @param userID
     * @param toUserType
     */
    public void clearAtMe(int userID, byte toUserType) {
        IMStruct002 message = new IMStruct002();
        message.setToUserId(userID);
        message.setFromUserId(userID);
        message.setToUserType(toUserType);
        MessageModel model = this.getMessageModel(message);
        if (model == null) {
            return;
        }
        model.clearAtMe();

    }

    /**
     * 消息未读数量
     *
     * @param userID
     * @param toUserType
     * @return
     */
    public int getUnReadCount(int userID, byte toUserType) {
        IMStruct002 message = new IMStruct002();
        message.setToUserId(userID);
        message.setFromUserId(userID);
        message.setToUserType(toUserType);

        MessageModel model = this.getMessageModel(message);
        if (model == null) {
            return 0;
        }

        return model.getUnReadCount();
    }

    /**
     * 未读数量清0
     *
     * @param userID
     * @param toUserType
     */
    public void unreadZero(int userID, byte toUserType) {
        IMStruct002 message = new IMStruct002();
        message.setToUserId(userID);
        message.setFromUserId(userID);
        message.setToUserType(toUserType);

        MessageModel model = this.getMessageModel(message);
        if (model == null) {
            return;
        }
        model.unreadZero();

    }

    /**
     * 标记为未读状态
     *
     * @param message
     */
    public void markedAsUnread(IMStruct002 message) {
        if (message.getState() == IMStruct002.MESSAGE_STATE_UNREAD) {
            return;
        }

        MessageModel messageModel = this.getMessageModel(message);
        messageModel.messageUnread(message);
        changeMessageState(IMStruct002.MESSAGE_STATE_UNREAD, message);
    }

    /**
     * 标记为已读状态
     *
     * @param message
     */
    public void markedAsRead(IMStruct002 message) {
        message.setReadState(IMStruct002.MESSAGE_STATE_READ);
        if (message.getState() == IMStruct002.MESSAGE_STATE_READ) {
            return;
        }

        MessageModel messageModel = this.getMessageModel(message);
        messageModel.messageRead(message);
        changeMessageState(IMStruct002.MESSAGE_STATE_READ, message);
    }

    /**
     * 标记为发投递状态
     *
     * @param message
     */
    public void markedAsDliver(IMStruct002 message) {
        if (message.getState() == IMStruct002.MESSAGE_STATE_DELIVER) {
            return;
        }

        MessageModel messageModel = this.getMessageModel(message);
        changeMessageState(IMStruct002.MESSAGE_STATE_DELIVER, message);
    }

    /**
     * 标记为发送状态
     *
     * @param message
     */
    public void markedAsSend(IMStruct002 message) {
        if (message.getState() != IMStruct002.MESSAGE_STATE_SEND) {
            MessageModel messageModel = this.getMessageModel(message);
            messageModel.messageRead(message);
            changeMessageState(IMStruct002.MESSAGE_STATE_SEND, message);
        } else {
            return;
        }

    }

    /**
     * 改变message的状态(已读 未读 删除)
     *
     * @param code
     * @param message
     */
    private void changeMessageState(int code, IMStruct002 message) {
        this.changeMessageState(code, message, true);
    }

    /**
     * 改变message的状态(已读 未读 删除)
     *
     * @param code
     * @param message
     * @param isUpdateDB
     */
    private void changeMessageState(int code, IMStruct002 message,
                                    boolean isUpdateDB) {
        if (message.getState() <= code) {
            message.setState(code);

            for (int i = 0; i < listenerList.size(); i++) {
                JFMessageListener listener = listenerList.get(i);
                listener.onUpdate(code, message);
            }

            if (isUpdateDB) {
                // 改变SQLite消息的状态
                dbManager.update(message);
            }
        } else {
            return;
        }
    }

    //设置消息为撤回
    public void setMessageToRecall(String messageID) {
        setMessageToRecall(messageID, true);
    }

    public void setMessageToRecall(String messageID, boolean isRecall) {
        //1.修改内存的消息为撤回
        IMStruct002 imStruct002 = messageKeyMap.get(messageID);
        if (imStruct002 != null) {
            imStruct002.setRecall(isRecall);
        }
        //2.修改数据库消息为撤回
        MessageDBManager.getInstance().updateMessage2Recall(messageID, isRecall);
        //3.修改messageMap 中的消息(获取最后一条消息)
        IMStruct002 dbMessage = MessageDBManager.getInstance().queryForID(messageID);
        if (dbMessage != null) {
            byte toUserype = dbMessage.getToUserType();
            String id = toUserype + "" + dbMessage.getToUserId();
            MessageModel messageModel = messageMap.get(id);
            if (messageModel != null && messageModel.getLastMessage() != null) {
                messageModel.getLastMessage().setRecall(isRecall);
            }
        }
    }

    public static boolean isChannelActived() {
        return JFSocketManager.isChannelActived();
    }

    public static void dealloc() {
        Log.i("db-----", "JFMessageManager-----dealloc");
        manager = null;
        dbManager = null;
        messageModelDBManager = null;
        messageQueue.clear();
        readMessageQueue.clear();
        sqlHelper = null;
    }
}
